package com.jecy.base.baseproject.base.service;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.jecy.base.baseproject.base.BaseMapper;
import com.jecy.base.baseproject.base.domain.BaseEntity;
import com.jecy.base.baseproject.base.enums.SqlOrderEnum;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * <p>
 * <p>
 *
 * @author huijun
 * @create 2017-11-10 下午 7:40
 **/
@Transactional
public abstract class AbstractBaseService<T extends BaseEntity, M extends BaseMapper<T>> implements IBaseService<T> {

    @Autowired
    private M baseMapper;
    private Class<?> clazz = null;

    protected Class<?> getEntityClass() {
        if (clazz == null) {
            clazz = (Class<?>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        }
        return clazz;
    }

    @Override
    public List<T> select(T var1) {
        return baseMapper.select(var1);
    }

    @Override
    public T save(T entity) {
        Preconditions.checkNotNull(entity);
        baseMapper.insertUseGeneratedKeys(entity);
        return baseMapper.selectByPrimaryKey(ImmutableMap.of("id", entity.getId()));
    }

    @Override
    public boolean delete(T entity) {
        return baseMapper.delete(entity) > 0;
    }

    @Override
    public int selectCount(T var1) {
        return baseMapper.selectCount(var1);
    }

    @Override
    public T selectOne(T var1) {
        return baseMapper.selectOne(var1);
    }

    @Override
    public boolean updateByExample(T entity, Object obj) {
        return baseMapper.updateByExample(entity, obj) > 0;
    }

    @Override
    public List<T> selectAll() {
        return baseMapper.selectAll();
    }

    @Override
    public boolean updateByExampleSelective(T entity, Object obj) {
        return baseMapper.updateByExampleSelective(entity, obj) > 0;
    }

    @Override
    public boolean updateByConditionSelective(T entity, Map<String, Object> condition) {
        Example example = new Example(entity.getClass());
        Example.Criteria criteria = example.createCriteria();
        for (String field : condition.keySet()
                ) {
            criteria.andEqualTo(field, condition.get(field));
        }
        return baseMapper.updateByExampleSelective(entity, example) > 0;
    }

    @Override
    public List<T> selectByExample(Map<String, Object> condition) {
        Example example = new Example(getEntityClass());
        Example.Criteria criteria = example.createCriteria();
        for (String field : condition.keySet()
                ) {
            if (!"orderBy".equals(field)&& !"DescOrAsc".equals(field)) {
                criteria.andEqualTo(field, condition.get(field));
            }

        }
        if (condition.containsKey("orderBy") && condition.containsKey("DescOrAsc")) {//排序查询
            if ("desc".equals((String)condition.get("DescOrAsc"))) {
                example.orderBy((String) condition.get("orderBy")).desc();
            } else {
                example.orderBy((String) condition.get("orderBy")).asc();
            }

        }
        return baseMapper.selectByExample(example);
    }

    @Override
    public boolean updateByIdSelective(T entity, Long id) {
        Example example = new Example(entity.getClass());
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("id", id);
        return baseMapper.updateByExampleSelective(entity, example) > 0;
    }

    @Override
    public boolean updateById(T entity, Long id) {
        Example example = new Example(entity.getClass());
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("id", id);
        return baseMapper.updateByExample(entity, example) > 0;
    }

    @Override
    public boolean updateByListSelective(T entity, List<Long> ids) {
        Example example = new Example(entity.getClass());
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("id", ids);
        return baseMapper.updateByExampleSelective(entity, example) > 0;

    }


    @Override
    public int insertSelective(T entity) {
        return baseMapper.insertSelective(entity);
    }

    @Override
    public List<T> selectByRowBounds(T entity, RowBounds rowBounds) {

        return baseMapper.selectByRowBounds(entity, rowBounds);
    }

    /**
     * 条件查询分页
     *
     * @param condition
     * @param var2
     * @return
     */
    @Override
    public List<T> selectByConditionAndRowBounds(Map<String, Object> condition, RowBounds var2) {
        Example example = new Example(getEntityClass());
        Example.Criteria criteria = example.createCriteria();
        for (String field : condition.keySet()
                ) {
            if (!"orderBy".equals(field) && !"DescOrAsc".equals(field)) {
                criteria.andEqualTo(field, condition.get(field));
            }
        }
        if (condition.containsKey("orderBy") && condition.containsKey("DescOrAsc")) {//排序查询
            if ("desc".equals((String)condition.get("DescOrAsc"))) {
                example.orderBy((String) condition.get("orderBy")).desc();
            } else {
                example.orderBy((String) condition.get("orderBy")).asc();
            }

        }
        return baseMapper.selectByExampleAndRowBounds(example, var2);
    }


    /**
     * 条件查询分页
     *
     * @param condition
     * @param var2
     * @return
     */

    @Override
    public List<T> selectByConditionAndRowBoundsForEntity(Map<String, Object> condition, RowBounds var2) {
        Example example = new Example(getEntityClass());
        Example.Criteria criteria = null;
        if (condition.keySet().size() != 2) {
            criteria = example.createCriteria();
        }

        for (String field : condition.keySet()
                ) {
            if (!"orderBy".equals(field) && !"DescOrAsc".equals(field)) {
                criteria.andEqualTo(field, condition.get(field));
            }
        }
        if (condition.containsKey("orderBy") && condition.containsKey("DescOrAsc")) {//排序查询
            if ("desc".equals((String)condition.get("DescOrAsc"))) {
                example.orderBy((String) condition.get("orderBy")).desc();
            } else {
                example.orderBy((String) condition.get("orderBy")).asc();
            }

        }
        return baseMapper.selectByExampleAndRowBounds(example, var2);
    }


    @Override
    public List<T> selectByExample(Object object) {
        return this.baseMapper.selectByExample(object);
    }

    @Override
    public List<T> selectByExampleAndRowBounds(Object var1, RowBounds var2) {
        return this.baseMapper.selectByExampleAndRowBounds(var1, var2);
    }

    @Override
    public int insertUseGeneratedKeys(T entity) {
        return this.baseMapper.insertUseGeneratedKeys(entity);
    }

    @Override
    public List<T> listByCondition(Map<String, Object> condition, String orderBy, SqlOrderEnum sqlOrderEnum) {
        Example example = new Example(getEntityClass());
        Example.Criteria criteria = example.createCriteria();
        for (String field : condition.keySet()) {
            criteria.andEqualTo(field, condition.get(field));
        }
        if (StringUtils.isNotBlank(orderBy)) {
            if (sqlOrderEnum.getName().equals(SqlOrderEnum.DESC.getName())) {
                example.orderBy(orderBy).desc();
            } else {
                example.orderBy(orderBy).asc();
            }
        }
        return baseMapper.selectByExample(example);
    }

    @Override
    public List<T> listByConditionForPage(Map<String, Object> condition, String orderBy, SqlOrderEnum sqlOrderEnum, RowBounds var2) {
        Example example = new Example(getEntityClass());
        Example.Criteria criteria = example.createCriteria();
        for (String field : condition.keySet()) {
            criteria.andEqualTo(field, condition.get(field));
        }
        if (StringUtils.isNotBlank(orderBy)) {
            if (sqlOrderEnum.getName().equals(SqlOrderEnum.DESC.getName())) {
                example.orderBy(orderBy).desc();
            } else {
                example.orderBy(orderBy).asc();
            }
        }
        return baseMapper.selectByExampleAndRowBounds(example, var2);
    }

    @Override
    public int selectCount(Map<String, Object> condition, Class<T> clazz) {
        Example example = new Example(clazz);
        Example.Criteria criteria = example.createCriteria();
        for (String field : condition.keySet()) {
            criteria.andEqualTo(field, condition.get(field));
        }
        return this.baseMapper.selectCountByExample(example);
    }
}
